<!DOCTYPE html>
<html>
<head>
    <title>Cylindrical Capacitor Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #ffffff;
        }
    </style>
</head>
<body>
    <canvas id="capacitorCanvas" width="500" height="650"></canvas>
    <script>
        const canvas = document.getElementById('capacitorCanvas');
        const ctx = canvas.getContext('2d');

        // Parameters
        const cx = canvas.width / 2;
        const cy_top = 150;
        const h = 350;
        const cy_bottom = cy_top + h;

        const R_base = 20;
        const R = R_base;
        const R1 = 4 * R_base; // 80
        const R2 = 8 * R_base; // 160
        const perspective = 0.2;

        const mainColor = '#363636';
        const hatchColor = '#555555';

        // --- Helper Function to draw an arrow ---
        function drawArrow(ctx, x1, y1, x2, y2) {
            const headlen = 8;
            const dx = x2 - x1;
            const dy = y2 - y1;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle - Math.PI / 6), y2 - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle + Math.PI / 6), y2 - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- Drawing ---
        ctx.strokeStyle = mainColor;
        ctx.fillStyle = mainColor;
        ctx.lineWidth = 2;

        // 1. Draw Hatching (Dielectric Region)
        ctx.save();
        ctx.lineWidth = 1.5;
        ctx.strokeStyle = hatchColor;

        // Create clipping path for the hatched area
        ctx.beginPath();
        // Outer boundary
        ctx.moveTo(cx - R1, cy_top);
        ctx.lineTo(cx - R1, cy_bottom);
        ctx.arc(cx, cy_bottom, R1, Math.PI, 0, false);
        ctx.lineTo(cx + R1, cy_top);
        ctx.closePath();
        // Inner boundary (hole)
        ctx.moveTo(cx + R, cy_top);
        ctx.lineTo(cx + R, cy_bottom);
        ctx.arc(cx, cy_bottom, R, 0, Math.PI, true);
        ctx.lineTo(cx - R, cy_top);
        ctx.closePath();
        ctx.clip();

        // Draw diagonal hatching lines
        const hatchSpacing = 12;
        for (let i = -h; i < canvas.width; i += hatchSpacing) {
            ctx.beginPath();
            ctx.moveTo(i, cy_top);
            ctx.lineTo(i + h, cy_bottom);
            ctx.stroke();
        }
        ctx.restore();

        // 2. Draw Cylinder Outlines
        ctx.lineWidth = 2;
        ctx.strokeStyle = mainColor;

        // Function to draw one cylinder
        function drawCylinder(radius) {
            // Top ellipse
            ctx.beginPath();
            ctx.ellipse(cx, cy_top, radius, radius * perspective, 0, 0, 2 * Math.PI);
            ctx.stroke();
            // Body with rounded bottom
            ctx.beginPath();
            ctx.moveTo(cx - radius, cy_top);
            ctx.lineTo(cx - radius, cy_bottom);
            ctx.arc(cx, cy_bottom, radius, Math.PI, 0, false);
            ctx.lineTo(cx + radius, cy_top);
            ctx.stroke();
        }

        drawCylinder(R);
        drawCylinder(R1);
        drawCylinder(R2);

        // 3. Draw Center Axis
        ctx.save();
        ctx.strokeStyle = mainColor;
        ctx.lineWidth = 1;
        ctx.setLineDash([15, 5, 5, 5]);
        ctx.beginPath();
        ctx.moveTo(cx, cy_top - 60);
        ctx.lineTo(cx, cy_bottom + R2 + 20);
        ctx.stroke();
        ctx.restore();

        // 4. Draw Labels and Arrows
        ctx.lineWidth = 1.5;
        ctx.font = "italic 22px 'Times New Roman'";

        // R
        drawArrow(ctx, cx, cy_top, cx - R * 0.7, cy_top - R * perspective * 0.7);
        ctx.fillText("R", cx - 20, cy_top - 20);

        // R1
        drawArrow(ctx, cx, cy_top, cx + R1 * 0.6, cy_top - R1 * perspective * 0.4);
        ctx.fillText("R₁", cx + 25, cy_top - 20);
        
        // R2
        drawArrow(ctx, cx, cy_top, cx + R2 * 0.9, cy_top + R2 * perspective * 0.4);
        ctx.fillText("R₂", cx + R2 * 0.9 + 5, cy_top + R2 * perspective * 0.4 + 5);

        // Permittivity labels
        ctx.font = "italic 26px 'Times New Roman'";
        ctx.fillText("ε₀", cx - R1 - 45, cy_top + h / 2);
        ctx.fillText("εᵣ", cx - R - 35, cy_top + h / 2);

        // 5. Draw Ground Symbol
        ctx.lineWidth = 2;
        const groundX = cx + R2 + 40;
        const groundY = cy_top + h / 2;
        ctx.beginPath();
        ctx.moveTo(cx + R2, groundY);
        ctx.lineTo(groundX, groundY);
        ctx.lineTo(groundX, groundY + 10);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(groundX - 15, groundY + 10);
        ctx.lineTo(groundX + 15, groundY + 10);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(groundX - 10, groundY + 17);
        ctx.lineTo(groundX + 10, groundY + 17);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(groundX - 5, groundY + 24);
        ctx.lineTo(groundX + 5, groundY + 24);
        ctx.stroke();

        // 6. Draw Bottom Title
        ctx.fillStyle = mainColor;
        ctx.font = "24px 'SimSun'";
        ctx.textAlign = "center";
        ctx.fillText("题 8 图", cx, cy_bottom + R2 + 60);

    </script>
</body>
</html>